#pragma once
#include <iostream>
#include <sys/epoll.h>
#include "Log.hpp"
#include "Comm.hpp"

class Epoller
{
    void EpollCore(int fd, int events, int optype)
    {
        struct epoll_event ev;
        ev.events = events;
        ev.data.fd = fd;

        int n = ::epoll_ctl(_epfd, optype, fd, &ev);
        if (n < 0)
        {
            LOG(ERROR, "epoll_ctl error\n");
        }
        else
        {
            LOG(INFO, "epoll_ctl for fd : %d success\n", fd);
        }
    }

public:
    Epoller()
    {
        _epfd = ::epoll_create(128);
        if (_epfd < 0)
        {
            LOG(FATAL, "epoll_create error\n");
            exit(EPOLL_CREATE_ERROR);
        }
        LOG(INFO, "epoll_create success, epfd : %d\n", _epfd);
    }
    void AddEvents(int fd, uint32_t events)
    {
        EpollCore(fd, events, EPOLL_CTL_ADD);
    }
    void ModEvents(int fd, uint32_t events)
    {
        EpollCore(fd, events, EPOLL_CTL_MOD);
    }
    void DelEvents(int fd)
    {
        ::epoll_ctl(fd, EPOLL_CTL_DEL, fd, nullptr);
    }
    int Wait(struct epoll_event revents[], int num, int timeout)
    {
        int n = ::epoll_wait(_epfd, revents, num, timeout);
        return n;
    }
    ~Epoller()
    {
        if (_epfd >= 0)
            ::close(_epfd);
    }

private:
    int _epfd = -1;
};